package cn.cosmosx.base.util;

import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;

/**
 * 泛型工具
 *
 * 注意：使用该工具的前提是，传入的class的 JavaBean 必须有一个匿名的空实现，否则无法真正获取其泛型
 *
 * 使用List举例：
 * <pre>
 *  {@code
 *       List<String> users = new ArrayList<>(); // 永远不会生效，getType(clazz)异常
 *       List<String> users = new ArrayList<String>(); // 永远不会生效，getType(clazz)异常
 *       // 正确使用方法，使用一个匿名实现就会生效，即在new一个泛型类时，末尾增加“{}”
 *       List<String> users = new ArrayList<String>(){};// 生效 getType(clazz) 拿到的就是java.lang.String
 *       // 对于自定义泛型类亦是如此
 *  }
 * </pre>
 */
public final class GenericUtil {

    /**
     * 获取泛型的实际类型
     *
     * @param bean - 泛型类实例
     * @return
     */
    public static Type getType(Object bean) {
        return getType(bean.getClass());
    }

    /**
     * 获取泛型的实际类型
     *
     * @param clazz - 泛型类
     * @return
     */
    public static Type getType(Class<?> clazz) {
        Type type = clazz.getGenericSuperclass();
        if (type instanceof ParameterizedType) {
            ParameterizedType parameterizedType = (ParameterizedType) type;
            Type[] actualTypeArguments = parameterizedType.getActualTypeArguments();
            return actualTypeArguments[0];
        }
        throw new RuntimeException("Miss type parameter");
    }
}
